#include "CreatureMgr.h"
#include "Character/PlayerMgr.h"
#include "monster/Monster.h"
#include "npc/Npc.h"
#include "drop/Drop.h"

#include "object/Object.h"
#include "Rebot/Rebot.h"
#include "MovePart.h"
#include "SkillPart.h"
#include "PackagePart.h"
#include "MissionPart.h"
#include "ChatPart.h"
#include "DuplicatePart.h"
#include "DeputyPart.h"
#include "Character/BuffPart.h"
#include "AchievementPart.h"
#include "TreasurePart.h"
#include "CollectPart.h"
#include "Character/PvpPart.h"
#include "Character/GodPart.h"
#include "Character/RunBusinessPart.h"
#include "Character/newAI/behaviac/CreatureCommonAI.h"
#include "Character/TitlePart.h"
#include "Character/welfare/OperateWelfarePart.h"
#include "Character/OperateLimitPart.h"
#include "Character/HuoYueDuPart.h"
#include "PlaneMgr/PlaneMgr.h"
#include "Scene/SceneMgr.h"
#include "Character/horse/HorsePart.h"
#include "Character/PandosPart.h"
#include "Character/PayPart.h"
#include "Character/AdventurePart.h"

CreatureMgr::CreatureMgr()
{
	m_creatureId = 0;
	m_pPlayerPool = nullptr;
	m_pMonsterPool = nullptr;
	m_pNpcPool = nullptr;
	m_pDropPool = nullptr;
	m_pObjectPool = nullptr;
	m_pRebotPool = nullptr;

	m_pMovePool = nullptr;
	m_pSkillPool = nullptr;
	m_pBuffPool = nullptr;
	m_pPackagePool = nullptr;
	m_pMissionPoll = nullptr;
	m_pChatPoll = nullptr;
	m_pDuplicatePool = nullptr;
	m_pAchievementPool = nullptr;
	m_pDeputyPool = nullptr;
	m_pPvpPool = nullptr;
	m_pTreasurePool = nullptr;
	m_pRunBusinessPool = nullptr;
	m_pWelfarePartPool = nullptr;
	m_pOperateLimitPartPool = nullptr;
	m_huoYueDuPartPool = nullptr;
	m_pHorsePartPool = nullptr;
	m_pGodPartPool = nullptr;
	m_pPandosPool = nullptr;
	m_pPayPool = nullptr;
	m_pAdventurePool = nullptr;

	m_debugStartTime = Time::Now().sec();
}

CreatureMgr::~CreatureMgr()
{

}

bool CreatureMgr::Init()
{
	//以下是生物
	m_pPlayerPool = new ObjectPool<Player>(500, false);
	m_pMonsterPool = new ObjectPool<Monster>(5000, false);
	m_pNpcPool = new ObjectPool<Npc>(200, false);

	m_pDropPool = new ObjectPool<Drop>(500, false);
	m_pObjectPool = new ObjectPool<Object>(200, false);
	m_pRebotPool = new ObjectPool<CRebot>(100, false);

	//以下是部件
	m_pMovePool = new ObjectPool<MovePart>(500, false);
	m_pSkillPool = new ObjectPool<SkillPart>(500, false);
	m_pPackagePool = new ObjectPool<PackagePart>(500, false);
	m_pMissionPoll = new ObjectPool<MissionPart>(500, false);
	m_pChatPoll = new ObjectPool<ChatPart>(500, false);
	m_pDuplicatePool = new ObjectPool<DuplicatePart>(500, false);
	m_pBuffPool = new ObjectPool<BuffPart>(500, false);
	m_pAchievementPool = new ObjectPool<AchievementPart>(500, false);
	m_pDeputyPool = new ObjectPool<DeputyPart>(500, false);
	m_pPvpPool = new ObjectPool<PvpPart>(500, false);
	m_pTreasurePool = new ObjectPool<TreasurePart>(500, false);
	m_pCollectPool = new ObjectPool<CollectPart>(500, false);
	m_pRunBusinessPool = new ObjectPool<RunBusinessPart>(500, false);
	m_pTitlePartPool = new ObjectPool<TitlePart>(500, false);
	m_pWelfarePartPool = new ObjectPool<OperateWelfarePart>(500, false);
	m_pOperateLimitPartPool = new ObjectPool<OperateLimitPart>(500, false);
	m_huoYueDuPartPool = new ObjectPool<HuoYueDuPart>(500, false);
	m_pHorsePartPool = new ObjectPool<HorsePart>(500, false);
	m_pGodPartPool = new ObjectPool<GodPart>(500, false);
	m_pPandosPool = new ObjectPool<PandosPart>(500, false);
	m_pPayPool = new ObjectPool<PayPart>(500, false);
	m_pAdventurePool = new ObjectPool<AdventurePart>(500, false);
	m_pDoubleListPool = new ObjectPool<DoubleListViewData>(1000000,false);	//视野结构
	m_pDoubleNodePool = new ObjectPool<DoubleNode>(1000000, false);	//视野结构
	m_mapPlayer.clear();
	//m_destoryPlayer.clear();
	m_allCreature.clear();
	m_destoryCreature.clear();

	//订阅切换逻辑节点事件
	g_GetEvent()->Subscribe(this, EVENT_TRANS_SUCCESS, 0, CREATURE_PLAYER, "CreatureMgr::Init()");
	g_GetEvent()->Subscribe(this, EVENT_TRANS_CHECK_RES, 0, CREATURE_PLAYER, "CreatureMgr::Init()");	

	return true;
}

bool CreatureMgr::UnInit()
{
	g_GetEvent()->UnSubscribeAll(this);
	//统一回收游戏中所有生物
	MAP_Creature::iterator iter = m_allCreature.begin();
	for (; iter != m_allCreature.end(); ++iter)
	{
		if (nullptr != iter->second)
		{
			iter->second->UnInit();
			RecyleCreature(iter->second);
			iter->second = nullptr;
		}
	}

	iter = m_destoryCreature.begin();
	for (; iter != m_destoryCreature.end(); ++iter)
	{
		if (nullptr != iter->second)
		{
			iter->second->UnInit();
			RecyleCreature(iter->second);
			iter->second = nullptr;
		}
	}

	MMO_DELETE(m_pPlayerPool);
	MMO_DELETE(m_pMonsterPool);
	MMO_DELETE(m_pNpcPool);

	MMO_DELETE(m_pDropPool);
	MMO_DELETE(m_pObjectPool);
	MMO_DELETE(m_pRebotPool);
	MMO_DELETE(m_pMovePool);
	MMO_DELETE(m_pSkillPool);
	MMO_DELETE(m_pPackagePool);
	MMO_DELETE(m_pMissionPoll);
	MMO_DELETE(m_pChatPoll);
	MMO_DELETE(m_pDuplicatePool);
	MMO_DELETE(m_pBuffPool);
	MMO_DELETE(m_pAchievementPool);
	MMO_DELETE(m_pDeputyPool);
	MMO_DELETE(m_pPvpPool);
	MMO_DELETE(m_pTreasurePool);
	MMO_DELETE(m_pCollectPool);
	MMO_DELETE(m_pRunBusinessPool);
	MMO_DELETE(m_pTitlePartPool);
	MMO_DELETE(m_pWelfarePartPool);
	MMO_DELETE(m_pOperateLimitPartPool);
	MMO_DELETE(m_huoYueDuPartPool);
	MMO_DELETE(m_pHorsePartPool);
	MMO_DELETE(m_pGodPartPool);
	MMO_DELETE(m_pPandosPool);
	MMO_DELETE(m_pPayPool);
	MMO_DELETE(m_pAdventurePool);
	MMO_DELETE(m_pDoubleListPool);
	MMO_DELETE(m_pDoubleNodePool);

	m_mapPlayer.clear();
	//m_destoryPlayer.clear();
	m_allCreature.clear();
	m_destoryCreature.clear();

	return true;
}

void CreatureMgr::Update(uint64_t tick)
{
	MAP_Creature::iterator iter = m_destoryCreature.begin();
	for (; iter != m_destoryCreature.end();)
	{
		if (nullptr != iter->second)
		{
			//判断是否要销毁 玩家的销毁不会通过这里
			if (iter->second->IsDestory() && iter->second->CreatureKind() != CREATURE_PLAYER)
			{
				iter->second->UnInit();
				RecyleCreature(iter->second);
				iter = m_destoryCreature.erase(iter);
			}
			else
			{
				++iter;
			}
		}
		else
		{
			++iter;
		}
	}

	
	//if (Time::Now().sec()- m_debugStartTime >=10)
	//{
	//	m_debugStartTime = Time::Now().sec();
	//	DebugLog();
	//	g_GetSkillMgr()->DebugLog();
	//}
}

Creature* CreatureMgr::MallocCreature(CreatureType type)
{
	switch (type)
	{
	case CREATURE_PLAYER:
		return (Creature*)m_pPlayerPool->MallocObj();
	case CREATURE_MONSTER:
		return (Creature*)m_pMonsterPool->MallocObj();
	case CREATURE_NPC:
		return (Creature*)m_pNpcPool->MallocObj();
	case CREATURE_DROP:
		return (Creature*)m_pDropPool->MallocObj();
	case CREATURE_OBJECT:
		return (Creature*)m_pObjectPool->MallocObj();
	case CREATURE_REBOT:
		return (Creature*)m_pRebotPool->MallocObj();
		default:
		return nullptr;
	}
}

void CreatureMgr::RecyleCreature(Creature* pCreature)
{
	switch ((CreatureType)pCreature->CreatureKind())
	{
	case CREATURE_PLAYER:
	{
		Player* pObj = dynamic_cast<Player*>(pCreature);
		if (pObj)
			m_pPlayerPool->FreeObj(pObj);
		break;
	}
	case CREATURE_MONSTER:
	{

							 Monster* pObj = dynamic_cast<Monster*>(pCreature);
							 if (pObj)
								 m_pMonsterPool->FreeObj(pObj);
		break;
	}
	case CREATURE_NPC:
	{
		Npc* pObj = dynamic_cast<Npc*>(pCreature);
		if (pObj)
			m_pNpcPool->FreeObj(pObj);
		break;
	}
	case CREATURE_DROP:
	{
		Drop* pObj = dynamic_cast<Drop*>(pCreature);
		if (pObj)
			m_pDropPool->FreeObj(pObj);
		break;
	}
	case CREATURE_OBJECT:
	{
		Object* pObj = dynamic_cast<Object*>(pCreature);
		if (pObj)
			m_pObjectPool->FreeObj(pObj);			
		break;
	}
	case CREATURE_REBOT:
	{
		CRebot* pObj = dynamic_cast<CRebot*>(pCreature);
		if (pObj)
			m_pRebotPool->FreeObj(pObj);
		break;
	}
	default:
		return;
	}
	return;
}

Part* CreatureMgr::CreatePart(uint32_t partType, Creature *pCreature, CharacterDBInfo *playerInfo /* = nullptr */)
{
	Part *pPart = nullptr;
	switch (partType)
	{
	case PART_MOVE:
		pPart = m_pMovePool->MallocObj();
		break;
	case PART_SKILL:
		pPart = m_pSkillPool->MallocObj();
		break;
	case PART_BUFF:
		pPart = m_pBuffPool->MallocObj();
		break;
	case PART_PACKAGE:
		pPart = m_pPackagePool->MallocObj();
		break;
	case PART_MISSION:
		pPart = m_pMissionPoll->MallocObj();
		break;
	case PART_CHAT:
		pPart = m_pChatPoll->MallocObj();
		break;
	case PART_DUPLICATE:
		pPart = m_pDuplicatePool->MallocObj();
		break;
	case PART_ACHIEVEMENT:
		pPart = m_pAchievementPool->MallocObj();
		break;
	case PART_DEPUTY:
		pPart = m_pDeputyPool->MallocObj();
		break;
	case PART_PVP:
		pPart = m_pPvpPool->MallocObj();
		break;
	case PART_TREASURE:
		pPart = m_pTreasurePool->MallocObj();
		break;
	case PART_COLLECT:
		pPart = m_pCollectPool->MallocObj();
		break;
	case PART_RUNBUSINESS:
		pPart = m_pRunBusinessPool->MallocObj();
		break;
	case PART_TITLE:
		pPart = m_pTitlePartPool->MallocObj();
		break;
	case PART_WELFARE:
		pPart = m_pWelfarePartPool->MallocObj();
		break;
	case PART_OPERATELIMIT:
		pPart = m_pOperateLimitPartPool->MallocObj();
		break;
	case PART_HUOYUEDU:
		pPart = m_huoYueDuPartPool->MallocObj();
		break;
	case PART_HORSE:
		pPart = m_pHorsePartPool->MallocObj();
		break;
	case  PART_GOD:
		pPart = m_pGodPartPool->MallocObj();
		break;
	case PART_PANDOS:
		pPart = m_pPandosPool->MallocObj();
		break;
	case PART_PAY:
		pPart = m_pPayPool->MallocObj();
		break;
	case PART_ADVENTURE:
		pPart = m_pAdventurePool->MallocObj();
		break;
	default:
		break;
	}
	if (!pPart || !pPart->Init(pCreature, partType, playerInfo))
		return nullptr;
	return pPart;
}

void CreatureMgr::RecylePart(Part *pPart)
{
	if (!pPart)
	{
		return;
	}

	uint32_t partType = pPart->getPartType();

	if (!pPart->UnInit())
		return;

	switch (partType)
	{
	case PART_MOVE:
		m_pMovePool->FreeTrack(dynamic_cast<MovePart*>(pPart));
		break;
	case PART_SKILL:
		m_pSkillPool->FreeTrack(dynamic_cast<SkillPart*>(pPart));
		break;
	case PART_BUFF:
		m_pBuffPool->FreeTrack(dynamic_cast<BuffPart*>(pPart));
		break;
	case PART_PACKAGE:
		m_pPackagePool->FreeTrack(dynamic_cast<PackagePart*>(pPart));
		break;
	case PART_MISSION:
		m_pMissionPoll->FreeTrack(dynamic_cast<MissionPart*>(pPart));
		break;
	case PART_CHAT:
		m_pChatPoll->FreeTrack(dynamic_cast<ChatPart*>(pPart));
		break;
	case PART_DUPLICATE:
		m_pDuplicatePool->FreeTrack(dynamic_cast<DuplicatePart*>(pPart));
		break;
	case PART_ACHIEVEMENT:
		m_pAchievementPool->FreeTrack(dynamic_cast<AchievementPart*>(pPart));
		break;
	case PART_DEPUTY:
		m_pDeputyPool->FreeTrack(dynamic_cast<DeputyPart*>(pPart));
		break;
	case PART_PVP:
		m_pPvpPool->FreeTrack(dynamic_cast<PvpPart*>(pPart));
		break;
	case PART_TREASURE:
		m_pTreasurePool->FreeTrack(dynamic_cast<TreasurePart*>(pPart));
		break;
	case PART_COLLECT:
		m_pCollectPool->FreeTrack(dynamic_cast<CollectPart*>(pPart));
		break;
	case PART_RUNBUSINESS:
		m_pRunBusinessPool->FreeTrack(dynamic_cast<RunBusinessPart*>(pPart));
		break;
	case PART_TITLE:
		m_pTitlePartPool->FreeTrack(dynamic_cast<TitlePart*>(pPart));
		break;
	case PART_WELFARE:
		m_pWelfarePartPool->FreeTrack(dynamic_cast<OperateWelfarePart*>(pPart));
		break;
	case PART_OPERATELIMIT:
		m_pOperateLimitPartPool->FreeTrack(dynamic_cast<OperateLimitPart*>(pPart));
		break;
	case PART_HUOYUEDU:
		m_huoYueDuPartPool->FreeTrack(dynamic_cast<HuoYueDuPart*>(pPart));
		break;
	case PART_HORSE:
		m_pHorsePartPool->FreeTrack(dynamic_cast<HorsePart*>(pPart));
		break;
	case PART_GOD:
		m_pGodPartPool->FreeTrack(dynamic_cast<GodPart*>(pPart));
		break;
	case PART_PANDOS:
		m_pPandosPool->FreeTrack(dynamic_cast<PandosPart*>(pPart));
		break;
	case PART_PAY:
		m_pPayPool->FreeTrack(dynamic_cast<PayPart*>(pPart));
		break;
	case PART_ADVENTURE:
		m_pAdventurePool->FreeTrack(dynamic_cast<AdventurePart*>(pPart));
		break;
	default:
		break;
	}
}


void CreatureMgr::OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen)
{
	switch (nEventID)
	{
	case EVENT_TRANS_SUCCESS:
		{
			CreatureTransParam param;
			if (!param.ParseFromArray(pContext,nLen))
			{
				LogErrFmtPrint("[logic] CreatureMgr::OnExecute....CreatureTransParam parse failed...eventid:%u, src:%llu, type:%d ",nEventID,nSrcID,bySrcType);
				return;
			}
			OnCreatureChangeLogic(param);
		}
		break;
	case EVENT_TRANS_CHECK_RES:
		{
			if (nLen < (int32_t)sizeof(TransCheckResEvent))
			{
				LogErrFmtPrint("[logic] CreatureMgr::OnExecute....nLen < sizeof(TransCheckResEvent) ...eventid:%u, src:%llu, type:%d, len:%d  ", nEventID, nSrcID, bySrcType,nLen);
				return;
			}
			TransCheckResEvent *pResEvent = (TransCheckResEvent*)pContext;
			OnCreatureChangeLogicCheckRes(pResEvent);
		}
		break;
	}
}

Player* CreatureMgr::GetPlayer(CharIDType PlayerId)
{
	return g_GetSceneMgr()->GetPlayer(PlayerId);
}

//获取非场景玩家指针
Player* CreatureMgr::GetNoScenePlayer(CharIDType PlayerId)
{
	MAP_Player::iterator iter = m_mapPlayer.find(PlayerId);
	if (iter == m_mapPlayer.end())
		return nullptr;
	return iter->second;
}

void CreatureMgr::RecylePlayer(CharIDType playerId)
{
	MAP_Player::iterator iter = m_mapPlayer.find(playerId);
	if (iter == m_mapPlayer.end())
		return;

	Player *pPlayer = iter->second;
	m_mapPlayer.erase(iter);
	m_allCreature.erase(playerId);

	if (!pPlayer)
		return;

	pPlayer->UnInit();

	RecyleCreature(pPlayer);

	//m_onlineList.RemoveTail(pPlayer->GetHostNode());

	pPlayer = nullptr;
}

Player* CreatureMgr::CreatePlayer(CharLoginInfo* pLoginInfo, CharacterDBInfo &playerInfo, bool change)
{
	Player *pPlayer = dynamic_cast<Player*>(MallocCreature(CREATURE_PLAYER));
	if (nullptr == pPlayer)
	{
		LogErrFmtPrint("[logic] PlayerMgr::CreatePlayer....nullptr == pPlayer, playerid:", playerInfo.charid());
		return nullptr;
	}

	m_mapPlayer[playerInfo.charid()] = pPlayer;
	m_allCreature[playerInfo.charid()] = pPlayer;
	if (!pPlayer->Init(playerInfo, pLoginInfo))
	{
		m_mapPlayer.erase(playerInfo.charid());
		m_allCreature.erase(playerInfo.charid());

		pPlayer->UnInit();
		RecyleCreature(pPlayer);

		LogErrFmtPrint("[logic] PlayerMgr::CreatePlayer....create player fail, playerid:", playerInfo.charid());
		return nullptr;
	}

	//先把玩家加入到在线列表
	//m_onlineList.AddTail(pPlayer->GetHostNode());

	//这个先拿在创建外面，玩家进游戏了发送玩家信息后，再进入场景
	//if (false == pPlayer->LoginInGame(change))
	//{
	//	//进入游戏失败的话 该接口会去移除在线列表
	//	RecylePlayer(playerInfo.charid());
	//	return nullptr;
	//}

	return pPlayer;
}

int CreatureMgr::GetPlayerCount()
{
	return m_mapPlayer.size();
}


void CreatureMgr::ClearAllPlayerActiveAnswerData()
{
	MAP_Player::iterator iter = m_mapPlayer.begin();
	for (; iter != m_mapPlayer.end();++iter)
	{
		if (iter->second)
		{
			iter->second->ClearAnswerActiveData();
		}
	}
}


bool CreatureMgr::SaveAllPlayer()
{
	LogInfoFmtPrint("[logic] CreatureMgr::SaveAllPlayer....size:%d", m_mapPlayer.size());
	MAP_Player logoutPlayerMap = m_mapPlayer;
	MAP_Player::iterator iter = logoutPlayerMap.begin();
	for (; iter != logoutPlayerMap.end(); ++iter)
	{
		Player *pPlayer = iter->second;
		if (nullptr != pPlayer)
		{
			//走一下logout操作
			pPlayer->Logout(LOGOUT_TYPE_LOGOUT);
			//回收玩家内存
			RecylePlayer(pPlayer->GetCid());

		}
	}

	return true;
}

//每日零点更新
bool CreatureMgr::DailyUpdate(uint64_t unixSec)
{
	MAP_Player::iterator iter = m_mapPlayer.begin();
	for (; iter != m_mapPlayer.end(); ++iter)
	{
		Player *pPlayer = iter->second;
		if (nullptr != pPlayer)
		{
			pPlayer->DailyUpdate(unixSec);
		}
	}
	return true;
}
//每周零点刷新
bool CreatureMgr::WeekUpdate(uint64_t unixSec)
{
	MAP_Player::iterator iter = m_mapPlayer.begin();
	for (; iter != m_mapPlayer.end(); ++iter)
	{
		Player *pPlayer = iter->second;
		if (nullptr != pPlayer)
		{
			pPlayer->WeekUpdate(unixSec);
		}
	}
	return true;
}
//每日零点更新
bool CreatureMgr::DailyZeroUpdate(uint64_t unixSec)
{
	MAP_Player::iterator iter = m_mapPlayer.begin();
	for (; iter != m_mapPlayer.end(); ++iter)
	{
		Player *pPlayer = iter->second;
		if (nullptr != pPlayer)
		{
			pPlayer->DailyZeroUpdate(unixSec);
		}
	}
	return true;
}
//每周零点刷新
bool CreatureMgr::WeekZeroUpdate(uint64_t unixSec)
{
	MAP_Player::iterator iter = m_mapPlayer.begin();
	for (; iter != m_mapPlayer.end(); ++iter)
	{
		Player *pPlayer = iter->second;
		if (nullptr != pPlayer)
		{
			pPlayer->WeekZeroUpdate(unixSec);
		}
	}
	return true;
}

//更新活动状态
bool CreatureMgr::UpdateActivityState(uint32_t actId)
{
	MAP_Player::iterator iter = m_mapPlayer.begin();
	for (; iter != m_mapPlayer.end(); ++iter)
	{
		Player *pPlayer = iter->second;
		if (nullptr != pPlayer)
		{
			MissionPart *pMissionPart = dynamic_cast<MissionPart*>(pPlayer->GetPart(PART_MISSION));
			if (nullptr != pMissionPart)
			{
				pMissionPart->OnActivityState(actId);
			}
		}
	}
	return true;
}



void CreatureMgr::GetGateClientIds(MAP_UINT32_LST_UINT32& gateClientsMap, SET_UINT64& charIds)
{
	auto iter = charIds.begin();
	auto iterEnd = charIds.end();
	Player *pPlayer = nullptr;
	uint32_t gateId = 0;
	uint32_t clientId = 0;

	for (; iter != iterEnd; iter++)
	{
		pPlayer = GetPlayer(*iter);
		if (nullptr == pPlayer)
		{
			continue;
		}

		pPlayer->GetGateClientId(gateId, clientId);
		LIST_UINT32& lstClientIds = gateClientsMap[gateId];
		lstClientIds.push_back(clientId);
	}
}

void CreatureMgr::GetGateClientId(CharIDType cid, uint32_t& gateId, uint32_t& clientId)
{
	Player* pPlayer = GetPlayer(cid);
	if (nullptr == pPlayer)
		return;
	pPlayer->GetGateClientId(gateId, clientId);
}


AccountGameState CreatureMgr::GetPlayerAccountState(CharIDType cid)
{
	Player* pPlayer = GetPlayer(cid);
	if (nullptr == pPlayer)
		return AccountGameState::ACCOUNT_GAME_STATE_NULL;
	return pPlayer->GetAccountState();
}

Creature* CreatureMgr::GetCreature(CharIDType cid)
{
	return g_GetSceneMgr()->GetCreature(cid);
}
Creature* CreatureMgr::GetNoSceneCreature(CharIDType cid)
{
	MAP_Creature::iterator iter = m_allCreature.find(cid);
	return (iter != m_allCreature.end()) ? iter->second : nullptr;
}

//创建怪物 monsIdx：怪物对应json中所在数组的索引（>= 0） ，默认索引值设置为 -1（有些怪物是动态创建的是没有索引）
Monster* CreatureMgr::CreateMonster(uint32_t monsterId, uint32_t sceneId, Point3<float> bornPos, MonsCreateParam &createParam, Point3<float> dir, int32_t monsIdx /*= -1*/, MonsterExtendInfo * pExtend, CharIDType createrID, uint32_t monsterGroup)
{
	Monster* pmonster =  dynamic_cast<Monster*>(MallocCreature(CREATURE_MONSTER));

	if (nullptr == pmonster)
	{
		LogErrFmtPrint("monster pool malloc failed");
		return nullptr;
	}
	uint64_t mons_cid = NextId();
	m_allCreature[mons_cid] = pmonster; //需要先加到map中
	if (!pmonster->Born(mons_cid, monsterId, sceneId, bornPos, createParam, dir, monsIdx, pExtend, monsterGroup))
	{
		m_allCreature.erase(mons_cid);
		LogErrFmtPrint("create monster fail, monster:");
		pmonster->UnInit();
		RecyleCreature(pmonster);
		return nullptr;
	}

	//LogAlwaysFmtPrint("create monste cid=%lu", mons_cid);
	//如果该怪物是专属怪，则直接把创建者设置成他主人
	if (pmonster->IsOnlyOnwerOnePlayerMonster() && createrID>0)
	{
		pmonster->SetMonsterMasterCID(createrID);
	}

	//是否是位面判断
	if (createrID>0)
	{
		Creature * pCreature = GetCreature(createrID);
		if (pCreature)
		{
			uint64_t planeID = pCreature->GetPlaneID();
			if (planeID>0)
			{
				//LogAlwaysFmtPrint("add plane");
				g_GetPlaneMgr()->AddCreature(planeID,pmonster->GetCid());
			}
		}
	}

	if (pmonster->GetMonsterGroupId() > 0)
	{
		MonsterGroupAddMonster(sceneId, pmonster->GetMonsterGroupId(), pmonster);
	}

	return pmonster;
}

void CreatureMgr::RecyleMonster(Monster* pmonster)
{
	if (!pmonster)
		return;

	CharIDType cid = pmonster->GetCid();
	MAP_Creature::iterator iter = m_allCreature.find(cid);
	if (iter == m_allCreature.end())
		return;
	m_allCreature.erase(iter);

	if (!pmonster->UnInit())
		LogErrFmtPrint("monster recyle error can case link memery, monsterCid:%d, MonsterName:%s", pmonster->GetCid(), pmonster->GetCid());

	RecyleCreature(pmonster);
	pmonster = nullptr;
}

Monster* CreatureMgr::GetMonster(CharIDType monsterCid)
{
	/*MAP_Creature::iterator iter = m_allCreature.find(monsterCid);
	if (iter == m_allCreature.end())
		return nullptr;

	Monster* pMonster = dynamic_cast<Monster*>(iter->second);
	return pMonster;*/
	return g_GetSceneMgr()->GetMonster(monsterCid);
}

void CreatureMgr::SetAIEnable(bool use)
{
	for (MAP_Creature::iterator iter = m_allCreature.begin(); iter != m_allCreature.end(); iter++)
	{
		if (nullptr != iter->second)
		{
			if (iter->second->CreatureKind() == CREATURE_MONSTER)
			{
				Monster* pMonster = dynamic_cast<Monster*>(iter->second);
				if (nullptr != pMonster && nullptr != pMonster->GetAiData())
				{
					pMonster->GetAiData()->SetAiEnable(use);
				}
			}
		}
	}
}

Npc* CreatureMgr::CreateNpc(uint32_t npcId, uint32_t sceneId, Point3<float>& bornPos,int32_t npcIdx /*= -1*/)
{
	Npc* pNpc = dynamic_cast<Npc*>(MallocCreature(CREATURE_NPC));

	if (pNpc == nullptr)
	{
		return nullptr;
	}
	uint64_t npc_cid = NextId();
	m_allCreature[npc_cid] = pNpc;
	if (!pNpc->Born(npc_cid, npcId, sceneId, bornPos, npcIdx))
	{
		m_allCreature.erase(npc_cid);
		LogErrFmtPrint("create npc:npcId:%d failed , sceneId:%d", npcId, sceneId);
		pNpc->UnInit();
		RecyleCreature(pNpc);
		return nullptr;
	}

	if (pNpc->GetBattleInfo() && pNpc->GetBattleInfo()->npcTeam > 0)
	{
		NpcTeamAddNpc(sceneId, pNpc->GetBattleInfo()->npcTeam, pNpc, pNpc->GetBattleInfo()->npcSort);
	}

	return pNpc;
}

void CreatureMgr::RecyleNpc(Npc* pNpc)
{
	if (pNpc == nullptr)
	{
		return;
	}

	uint64_t cid = pNpc->GetCid();
	MAP_Creature::iterator it = m_allCreature.find(cid);
	if (it == m_allCreature.end())
	{
		return;
	}

	m_allCreature.erase(it);

	if (!pNpc->UnInit())
	{
		LogErrFmtPrint("npc recyle error, npcCid:%d unInit faield", cid);
	}

	RecyleCreature(pNpc);
	pNpc = nullptr;
}

Npc* CreatureMgr::GetNpc(CharIDType npcCid)
{
	/*MAP_Creature::iterator it = m_allCreature.find(npcCid);
	if (it == m_allCreature.end())
	{
		return nullptr;
	}

	Npc* pNpc = dynamic_cast<Npc*>(it->second);
	return pNpc;*/
	return g_GetSceneMgr()->GetNpc(npcCid);
}

Npc* CreatureMgr::GetNpc(uint32_t npcCnfigID)
{
	MAP_Creature::iterator iter = m_allCreature.begin();
	for (; iter != m_allCreature.end();++iter)
	{
		if (iter->second->CreatureKind()==CREATURE_NPC)
		{
			Npc * pNpc = dynamic_cast<Npc*>(iter->second);
			if (pNpc)
			{
				if (pNpc->GetConfigId() == npcCnfigID)
				{
					return pNpc;
				}
			}
		}
	}
	return nullptr;
}

std::list<Npc*>* CreatureMgr::GetNpcTeam(uint32_t sceneId, uint32_t teamId)
{
	auto sceneIter = m_npcTeam.find(sceneId);
	if (sceneIter != m_npcTeam.end())
	{
		auto it = sceneIter->second.find(teamId);
		if (it != sceneIter->second.end())
		{
			return &it->second;
		}
	}

	return nullptr;
}

std::list<Monster*>* CreatureMgr::GetMonsterGroup(uint32_t sceneId, uint32_t groupId)
{
	if (groupId <= 0) return nullptr;
	auto sceneIter = m_monsterGroup.find(sceneId);
	if (sceneIter != m_monsterGroup.end())
	{
		auto it = sceneIter->second.find(groupId);
		if (it != sceneIter->second.end())
		{
			return &it->second;
		}
	}

	return nullptr;
}

void CreatureMgr::MonsterGroupAddMonster(uint32_t sceneId, uint32_t groupId, Monster* pMonster)
{
	if (groupId <= 0) return;
	m_monsterGroup[sceneId][groupId].push_back(pMonster);
}

void CreatureMgr::MonsterGroupDelMonster(uint32_t sceneId, uint32_t groupId, Monster* pMonster)
{
	auto pGroup = GetMonsterGroup(sceneId, groupId);
	if (pGroup)
	{
		for(auto it = pGroup->begin(); it != pGroup->end(); it++)
		{
			if (*it == pMonster)
			{
				pGroup->erase(it);
				return;
			}
		}
	}
}

void CreatureMgr::NpcTeamAddNpc(uint32_t sceneId, uint32_t teamId, Npc* pNpc, uint32_t teamSort)
{
	auto pTeam = GetNpcTeam(sceneId, teamId);
	if (pTeam)
	{
		if (teamSort == 1)
		{
			pTeam->push_front(pNpc);
			for(auto iter = pTeam->begin(); iter != pTeam->end(); iter++)
			{
				auto pOtherNpc = *iter;
				if (pOtherNpc && pOtherNpc->GetAiData())
				{
					pOtherNpc->GetAiData()->SetTargetCid(0);
					pOtherNpc->GetAiData()->SetFollowCid(0);
					pOtherNpc->GetAiData()->GetPatrolPath().SetNextPatrolPathIndex(0);
					pOtherNpc->GetAiData()->GetPatrolPath().SetIsMoveToTarget(true);
					pOtherNpc->GetAiData()->ClearHateList();
					pOtherNpc->GetAiData()->ClearFightStatus();
					pOtherNpc->GetAiData()->NpcTeamSetFollower();
				}
			}
		}
		else
		{
			pTeam->push_back(pNpc);
		}
	}
	else
	{
		m_npcTeam[sceneId][teamId].push_back(pNpc);
	}
}

void CreatureMgr::NpcTeamDelNpc(uint32_t sceneId, uint32_t teamId, Npc* pNpc)
{
	auto pTeam = GetNpcTeam(sceneId, teamId);
	if (pTeam)
	{
		for(auto iter = pTeam->begin(); iter != pTeam->end(); iter++)
		{
			if (*iter == pNpc)
			{
				//the leader dead, clear other hate
				if (iter == pTeam->begin())
				{
					auto it = iter;
					it++;
					for(; it != pTeam->end(); it++)
					{
						auto pOtherNpc = *it;
						if (pOtherNpc && pOtherNpc->GetAiData())
						{
							pOtherNpc->GetAiData()->SetTargetCid(0);
							pOtherNpc->GetAiData()->SetFollowCid(0);

							pOtherNpc->GetAiData()->ClearHateList();
							pOtherNpc->GetAiData()->ClearFightStatus();
							pOtherNpc->GetAiData()->NpcTeamSetFollower();
						}
					}
				}
				pTeam->erase(iter);
				return;
			}
		}
	}
}

void CreatureMgr::NpcTeamSyncHate(uint32_t sceneId, uint32_t teamId, Npc* pNpc, CharIDType targetCid, uint32_t hateValue)
{
	Creature* pLeader = FindTeamLeader(sceneId, teamId);
	if (pLeader && !pLeader->IsDead() && pLeader->GetAiData())
	{
		pLeader->GetAiData()->AddHateTarget(targetCid, hateValue, 0);
	}
//	auto pTeam = GetNpcTeam(teamId);
//	if (pTeam && pTeam->)
//	{
//		for(auto iter = pTeam->begin(); iter != pTeam->end(); iter++)
//		{
//			if (*iter == pNpc)
//			{
//				continue;
//			}
//
//			auto pOtherNpc = *iter;
//			if (pOtherNpc)
//			{
//				auto pAiData = pOtherNpc->GetAiData();
//				if (pAiData)
//				{
//					pAiData->StopMove();
//					pAiData->AddHateTarget(targetCid, hateValue, 0);
//				}
//			}
//		}
//	}
}

bool CreatureMgr::IsTeamLeader(uint32_t sceneId, uint32_t teamId, Npc* pNpc)
{
	auto pTeam = GetNpcTeam(sceneId, teamId);
	if (pTeam)
	{
		auto iter = pTeam->begin();
		if (iter != pTeam->end())
		{
			if (*iter == pNpc)
			{
				return true;
			}
		}
	}
	return false;
}

Npc* CreatureMgr::FindTeamLeader(uint32_t sceneId, uint32_t teamId)
{
	auto pTeam = GetNpcTeam(sceneId, teamId);
	if (pTeam)
	{
		auto begin = pTeam->begin();
		if (begin != pTeam->end())
		{
			return *begin;
		}
	}
	return nullptr;
}

Npc* CreatureMgr::FindTeamFollower(uint32_t sceneId, uint32_t teamId, Npc* pNpc)
{
	auto pTeam = GetNpcTeam(sceneId, teamId);
	if (pTeam)
	{
		auto begin = pTeam->begin();
		for(auto iter = begin; iter != pTeam->end(); iter++)
		{
			if (iter == begin)
			{
				continue;
			}

			if (pNpc == *iter)
			{
				iter--;
				return *iter;
			}
		}
	}
	return nullptr;
}

Object *CreatureMgr::CreateObject(uint32_t nObjectId, uint32_t nSceneId, Point3<float>& bornPos, int32_t posIdx)
{
	Object *pObject = dynamic_cast<Object*>(MallocCreature(CREATURE_OBJECT));
	if (nullptr == pObject)
	{
		return nullptr;
	}
	uint64_t obj_cid = NextId();
	m_allCreature[obj_cid] = pObject;
	if (!pObject->Born(obj_cid, nObjectId, nSceneId, bornPos, posIdx))
	{
		m_allCreature.erase(obj_cid);
		LogErrFmtPrint("[logic] ObjectMgr::CreateObject...create object failed....objectId:%u , sceneid:%u ,posIdx:%d ", nObjectId, nSceneId, posIdx);
		RecyleCreature(pObject);
		return nullptr;
	}

	return pObject;
}

void CreatureMgr::RecycleObject(Object* pObject)
{
	if (pObject == nullptr)
	{
		return;
	}

	uint64_t cid = pObject->GetCid();
	MAP_Creature::iterator it = m_allCreature.find(cid);
	if (it == m_allCreature.end())
	{
		return;
	}

	m_allCreature.erase(it);

	if (!pObject->UnInit())
	{
		LogErrFmtPrint("npc recyle error, objectCid:%d unInit faield", cid);
	}

	RecyleCreature(pObject);
	pObject = nullptr;
}

void CreatureMgr::MasterEneterScene(Creature* pMaster, uint32_t sceneId, Point3<float>& enterPos)
{
	Scene* pScene = g_GetSceneMgr()->GetScene(sceneId);
	if (pScene == nullptr)
	{
		return;
	}
}

void CreatureMgr::MasterLeaveScene(Creature* pMaster)
{
}

Drop* CreatureMgr::CreateDropEx(CItemBase *pItem, uint32_t nGold, uint32_t nSceneID, Point3<float> &pos, int8_t byDropType, SET_UINT64 &setTypeVal, int32_t initProtect, SDropSourcePram &sourceParam, uint64_t fromWho/* = 0*/)
{
	if (nullptr == pItem && 0 == nGold) //物品和金币必须有一个有赋值的
	{
		return nullptr;
	}
	Drop *pDrop = dynamic_cast<Drop*>(MallocCreature(CREATURE_DROP));
	if (pDrop == nullptr)
	{
		return nullptr;
	}

	uint64_t drop_cid = NextId();
	m_allCreature[drop_cid] = pDrop;  //这个放进入场景前面，不然进入场景时，玩家不动，会看不到，因为进入场景的时候，玩家看到该ID，通过场景找不到对像

	if (!pDrop->Init() || !pDrop->Born(drop_cid, nSceneID, pos, byDropType, setTypeVal, pItem, nGold, initProtect,sourceParam, fromWho))
	{
		m_allCreature.erase(drop_cid);
		LogErrFmtPrint("create drop failed 11, sceneId:%d bornPos:%f,%f,%f", nSceneID, pos.x, pos.y, pos.z);
		//再回收掉落生物
		RecyleCreature(pDrop);
		return nullptr;
	}
	string strlog = "";
	int32_t tmpcount = 0;
	SET_UINT64::iterator iterVal = setTypeVal.begin();
	for (; iterVal != setTypeVal.end(); ++iterVal)
	{
		char szTmp[50] = { '\0' };
		snprintf(szTmp, sizeof(szTmp) - 1, "%lu,", (*iterVal));
		strlog += szTmp;
		++tmpcount;
		if (tmpcount >= 20)
		{
			//避免太长了，超过直接break
			break;
		}
	}

	if (nullptr != pItem)
	{
		LogDebugFmtPrint("[logic] drop item: nDropCid:%lu,nSceneID:%u, itemid:%u, item_num:%u, byDropType:%d,typeVal:%s, [%f,%f,%f],source:%u,sourceVal:%lu ", pDrop->GetCid(), nSceneID, pItem->GetItemID(), pItem->GetNum(), byDropType,strlog.c_str(), pos.x, pos.y, pos.z,(uint32_t)sourceParam.source,sourceParam.sourceVal);
	}
	else
	{
		LogDebugFmtPrint("[logic] drop gold: nDropCid:%lu,nSceneID:%u, gold:%u , byDropType:%d,typeVal:%s, [%f,%f,%f],source:%u,sourceVal:%lu ", pDrop->GetCid(), nSceneID, nGold, byDropType, strlog.c_str(), pos.x, pos.y, pos.z, (uint32_t)sourceParam.source, sourceParam.sourceVal);
	}
	return pDrop;
}

bool CreatureMgr::RecycleDrop(Drop *pDrop)
{
	if (nullptr == pDrop)
	{
		return false;
	}
	MAP_Creature::iterator iter = m_allCreature.find(pDrop->GetCid());
	if (iter == m_allCreature.end())
		return false;
	m_allCreature.erase(iter);

	if (!pDrop->UnInit())
		LogErrFmtPrint("drop recyle error can case link memery, dropCid:%lu ", pDrop->GetCid());

	RecyleCreature(pDrop);

	return true;
}

Drop *CreatureMgr::GetDrop(CharIDType dropCid)
{
	/*MAP_Creature::iterator iter = m_allCreature.find(dropCid);
	if (iter == m_allCreature.end())
	{
		return nullptr;
	}

	Drop* pDrop = dynamic_cast<Drop*>(iter->second);
	return pDrop;*/
	return g_GetSceneMgr()->GetDrop(dropCid);
}

CRebot* CreatureMgr::GetRebot(CharIDType rebotCid)
{
	/*MAP_Creature::iterator iter = m_allCreature.find(rebotCid);
	if (iter == m_allCreature.end())
	{
		return nullptr;
	}

	CRebot* pRebot = dynamic_cast<CRebot*>(iter->second);
	return pRebot;*/
	return g_GetSceneMgr()->GetRebot(rebotCid);
}

CRebot * CreatureMgr::CreateRebot(const CharacterMirrorData & stData)
{
	CharacterDBInfo playerInfo;
	if (stData.has_baseinfo())
	{
		CharacterDBBaseInfo* pBase = playerInfo.mutable_basedata();
		pBase->CopyFrom(stData.baseinfo());
	}
	if (stData.has_skills())
	{
		CharacterDBSkillData * pSkill = playerInfo.mutable_skilldata();
		pSkill->CopyFrom(stData.skills());
	}

	if (stData.has_buffs())
	{
		CharacterBuffData * pBuff = playerInfo.mutable_buffdata();
		pBuff->CopyFrom(stData.buffs());
	}

	if (stData.has_equips())
	{
		CharacterDBEquipData * pEquip = playerInfo.mutable_equipdata();
		pEquip->CopyFrom(stData.equips());
	}

	playerInfo.set_charid(NextId());
	//CRebot *pPlayerMirror = m_pRebotPool->MallocObj();
	CRebot *pPlayerMirror = dynamic_cast<CRebot*>(MallocCreature(CREATURE_REBOT));
	ENTER_ACCOUNT account;
	if (!pPlayerMirror || !pPlayerMirror->Init(playerInfo, &account))
	{
		LogErrFmtPrint("create playermirror fail, playerid:", playerInfo.charid());
		if (nullptr != pPlayerMirror)
		{
			pPlayerMirror->UnInit();
			RecyleCreature(pPlayerMirror);
		}		
		return nullptr;
	}
	m_allCreature[playerInfo.charid()] = pPlayerMirror;
	return pPlayerMirror;
}

CRebot * CreatureMgr::CreateRebot(uint32_t rebotID)
{
	//读表
	//CRebot *pRebot = m_pRebotPool->MallocObj();
	CRebot *pRebot = dynamic_cast<CRebot*>(MallocCreature(CREATURE_REBOT));
	CharIDType cid = NextId();
	if (!pRebot || !pRebot->Init(rebotID, cid))
	{
		LogErrFmtPrint("create rebot fail, rebotid:", rebotID);
		if (nullptr != pRebot)
		{
			pRebot->UnInit();
			RecyleCreature(pRebot);
		}
		return nullptr;
	}

	m_allCreature[cid] = pRebot;
	return pRebot;
}

void CreatureMgr::RecyleRebot(CRebot* pRebot)
{
	if (!pRebot)
	{
		return;
	}
	MAP_Creature::iterator iter = m_allCreature.find(pRebot->GetCid());
	if (iter == m_allCreature.end())
		return;

	m_allCreature.erase(iter);
	pRebot->UnInit();
	RecyleCreature(pRebot);
	pRebot = nullptr;
}

//生物切换逻辑节点
void CreatureMgr::OnCreatureChangeLogic(CreatureTransParam &param)
{
	int32_t creature_kind = param.creature_kind();
	if (CREATURE_PLAYER == creature_kind)
	{
		if (!param.has_player_param())
		{
			LogErrFmtPrint("[logic] CreatureMgr::OnCreatureChangeLogic.....param.has_player_param() false...creature_kind:%d ", creature_kind);
			return;
		}
		const PlayerTransParam &protoPlayer = param.player_param();
		CharacterDBInfo &protoCharDB = const_cast<CharacterDBInfo&>(protoPlayer.info());

		CharIDType charId = protoCharDB.charid();

		CharLoginInfo loginInfo;
		loginInfo.clientId = protoPlayer.client_id();
		loginInfo.sceneid = protoCharDB.basedata().enter_scene_id();
		loginInfo.mapid = protoCharDB.basedata().enter_map_id();
		loginInfo.x = protoCharDB.basedata().enterposx();
		loginInfo.y = protoCharDB.basedata().enterposy();
		loginInfo.z = protoCharDB.basedata().enterposz();
		loginInfo.gateId = protoPlayer.gateid();
		loginInfo.uid = protoPlayer.uid();
		loginInfo.channelId = protoPlayer.channid();
		loginInfo.protoLogin.CopyFrom(protoPlayer.center_data());
		loginInfo.sellItem.CopyFrom(protoPlayer.sell_items());
		if (param.has_type_param())
		{
			const SceneTransTypeParam& protoTransParam = param.type_param();
			loginInfo.transParam.srcMapId = protoTransParam.src_map();
			loginInfo.transParam.transType = protoTransParam.trans_type();
			loginInfo.transParam.dupId = protoTransParam.dup_id();
		}
		
		LogInfoFmtPrint("[logic] CreatureMgr::OnCreatureChangeLogic..charid:%llu, clientid:%u, sceneid:%u,mapid:%u,[%f,%f,%f] ",
						 charId, loginInfo.clientId, loginInfo.sceneid, loginInfo.mapid, loginInfo.x, loginInfo.y, loginInfo.z);

		Player *pPalyer = GetNoScenePlayer(charId);
		if (nullptr == pPalyer)
		{
			LogInfoFmtPrint("[logic] CreatureMgr::OnCreatureChangeLogic.. CreatePlayer....");
			pPalyer = CreatePlayer(&loginInfo, protoCharDB, true);
			if (!pPalyer)
			{
				LogErrFmtPrint("[logic] CreatureMgr::OnCreatureChangeLogic.....CreatePlayer faliled...charid:%llu, clientid:%u, sceneid:%u,mapid:%u,[%f,%f,%f] ", 
					charId, loginInfo.clientId, loginInfo.sceneid, loginInfo.mapid, loginInfo.x, loginInfo.y, loginInfo.z);
				return;
			}
		}
		LogInfoFmtPrint("[logic] CreatureMgr::OnCreatureChangeLogic.. LoginInGame....");
		if (!pPalyer->LoginInGame(loginInfo, true))
		{
			LogErrFmtPrint("[logic] CreatureMgr::OnCreatureChangeLogic.....player LoginInGame faliled...charid:%llu, clientid:%u, sceneid:%u,mapid:%u,[%f,%f,%f] ", 
				charId, loginInfo.clientId, loginInfo.sceneid, loginInfo.mapid, loginInfo.x, loginInfo.y, loginInfo.z);
			return;
		}

		//切逻辑节点，不走登录发送玩家基本信息流珵，这里就把宠物信息再同步一次
		//PetInfo msgPetInfo;
		//PlayerPetPart * pPart = dynamic_cast<PlayerPetPart *>(pPalyer->GetPart(PART_PET));
		//if (pPart)
		//{
		//	CPet * pPet = pPart->GetCurPet();
		//	if (pPet)
		//	{
		//		::ProtoBuf::CreaturesCreateData_Pet* pPetInfo = msgPetInfo.mutable_curfightpet();
		//		pPet->GetVisibleDataToClient(*pPetInfo);
		//		//发送消息给客户端
		//		pPalyer->SendDataToClient(LOGIC_TO_CLIENT_PET_INFO, &msgPetInfo);
		//	}
		//}
	}
}

//生物切换逻辑节点校验结果
void CreatureMgr::OnCreatureChangeLogicCheckRes(TransCheckResEvent *pCheckEvent)
{
	if (nullptr == pCheckEvent)
	{
		return;
	}
	LogInfoFmtPrint("[logic] CreatureMgr::OnCreatureChangeLogicCheckRes....result:%d, cid:%llu, dstsceneid:%u ", pCheckEvent->result,pCheckEvent->creature_cid,pCheckEvent->dst_sceneid);
	Creature *pCreature = GetNoSceneCreature(pCheckEvent->creature_cid);
	Player *pPlayer = dynamic_cast<Player*>(pCreature);
	if (nullptr != pPlayer) //玩家
	{
		if (RET_SUCCESS == pCheckEvent->result)
		{
			if (!g_GetPlayerMgr()->LeaveGame(pPlayer->GetCid(), pPlayer->GetUid(), pPlayer->GetClientId(), LOGOUT_TYPE_CHANGE_LOGIC))
			{
				LogErrFmtPrint("[logic] CreatureMgr::OnCreatureChangeLogicCheckRes.....g_GetPlayerMgr()->LeaveGame  failed...");
			}
		}
		else
		{
			//切逻辑服失败，设置成游戏状态
			pPlayer->SetAccountState(ACCOUNT_GAME_STATE_GAMING);
		}
	}
}

void CreatureMgr::WaitDestory(CharIDType creatureID)
{
	MAP_Creature::iterator iter = m_allCreature.find(creatureID);
	if (iter != m_allCreature.end())
	{
		if (nullptr != iter->second)
		{
			iter->second->SetDestory();
			MAP_Creature::iterator destoryIter = m_destoryCreature.find(creatureID);
			if (destoryIter != m_destoryCreature.end())
			{
				LogErrFmtPrint("[logic] CreatureMgr::WaitDestory fail because destoryIter != m_destoryCreature.end()...");
			}
			else
			{
				m_destoryCreature[creatureID] = iter->second;
				iter->second = nullptr;
				m_allCreature.erase(iter);
			}
		}
	}
}

void CreatureMgr::WaitDestory(Creature *pCreature)
{
	if (nullptr == pCreature)
	{
		return;
	}
	int8_t kind = pCreature->CreatureKind();
	CharIDType cid = pCreature->GetCid();
	if (CREATURE_PLAYER == kind)
	{
		//玩家的销毁不走这里
		return;
	}
	//等待销毁的生物必须是离开了场景的，生物管理器已经准备销毁生物，为避免场景那边此时还引用生物指针，这里做一次场景生物查询	
	if (nullptr != GetCreature(cid))
	{
		LogErrFmtPrint("[logic] CreatureMgr::WaitDestory...wait destory....but scene already exists creature....cid:%lu, kind:%d ", cid, kind);
		//场景那边此时还引用生物指针,为了避免场景那边出现无效生物指针，这里调用一次离开场景
	}
	pCreature->SetDestory();
	MAP_Creature::iterator destoryIter = m_destoryCreature.find(cid);
	if (destoryIter != m_destoryCreature.end())
	{
		LogErrFmtPrint("[logic] CreatureMgr::WaitDestory fail because destoryIter != m_destoryCreature.end()...cid:%lu, kind:%d ", cid, kind);
	}
	else
	{		
		//从生物列表中移除，加入等待销毁列表
		m_allCreature.erase(cid);
		m_destoryCreature[cid] = pCreature;
	}
}


void CreatureMgr::Destory(CharIDType creatureID)
{
	MAP_Creature::iterator iter = m_allCreature.find(creatureID);
	if (iter != m_allCreature.end())
	{
		if (nullptr != iter->second)
		{
			iter->second->UnInit();
			RecyleCreature(iter->second);
			iter->second = nullptr;
			m_allCreature.erase(iter);
		}
	}
}

void CreatureMgr::Destory(Creature *pCreature)
{
	if (nullptr == pCreature)
	{
		return;
	}
	CharIDType cid = pCreature->GetCid();
	pCreature->UnInit();
	RecyleCreature(pCreature);
	pCreature = nullptr;
	m_allCreature.erase(cid);
}


void CreatureMgr::DebugLog()
{
	/*static int32_t arrPool[100] = { 0 };
	LogDebugFmtPrint("Playerpool size=%d,difmem=%d", m_pPlayerPool->MemSize(), m_pPlayerPool->MemSize() - arrPool[0]);
	arrPool[0] = m_pPlayerPool->MemSize();
	LogDebugFmtPrint("Monster size=%d,difmem=%d", m_pMonsterPool->MemSize(), m_pMonsterPool->MemSize() - arrPool[1]);
	arrPool[1] = m_pMonsterPool->MemSize();
	LogDebugFmtPrint("Npc size=%d,difmem=%d", m_pNpcPool->MemSize(), m_pNpcPool->MemSize() - arrPool[2]);
	arrPool[2] = m_pNpcPool->MemSize();
	LogDebugFmtPrint("Drop size=%d,difmem=%d", m_pDropPool->MemSize(), m_pDropPool->MemSize() - arrPool[3]);
	arrPool[3] = m_pDropPool->MemSize();
	LogDebugFmtPrint("Object size=%d,difmem=%d", m_pObjectPool->MemSize(), m_pObjectPool->MemSize() - arrPool[4]);
	arrPool[4] = m_pObjectPool->MemSize();
	LogDebugFmtPrint("CRebot size=%d,difmem=%d", m_pRebotPool->MemSize(), m_pRebotPool->MemSize() - arrPool[5]);
	arrPool[5] = m_pRebotPool->MemSize();
	LogDebugFmtPrint("MovePart size=%d,difmem=%d", m_pMovePool->MemSize(), m_pMovePool->MemSize() - arrPool[6]);
	arrPool[6] = m_pMovePool->MemSize();
	LogDebugFmtPrint("SkillPart size=%d,difmem=%d", m_pSkillPool->MemSize(), m_pSkillPool->MemSize() - arrPool[7]);
	arrPool[7] = m_pSkillPool->MemSize();
	LogDebugFmtPrint("BuffPart size=%d,difmem=%d", m_pBuffPool->MemSize(), m_pBuffPool->MemSize() - arrPool[8]);
	arrPool[8] = m_pBuffPool->MemSize();
	LogDebugFmtPrint("PackagePart size=%d,difmem=%d", m_pPackagePool->MemSize(), m_pPackagePool->MemSize() - arrPool[9]);
	arrPool[9] = m_pPackagePool->MemSize();
	LogDebugFmtPrint("MissionPart size=%d,difmem=%d", m_pMissionPoll->MemSize(), m_pMissionPoll->MemSize() - arrPool[10]);
	arrPool[10] = m_pMissionPoll->MemSize();
	LogDebugFmtPrint("ChatPart size=%d,difmem=%d", m_pChatPoll->MemSize(), m_pChatPoll->MemSize() - arrPool[11]);
	arrPool[11] = m_pChatPoll->MemSize();
	LogDebugFmtPrint("DuplicatePart size=%d,difmem=%d", m_pDuplicatePool->MemSize(), m_pDuplicatePool->MemSize() - arrPool[12]);
	arrPool[12] = m_pDuplicatePool->MemSize();
	LogDebugFmtPrint("AchievementPart size=%d,difmem=%d", m_pAchievementPool->MemSize(), m_pAchievementPool->MemSize() - arrPool[13]);
	arrPool[13] = m_pAchievementPool->MemSize();
	LogDebugFmtPrint("DeputyPart size=%d,difmem=%d", m_pDeputyPool->MemSize(), m_pDeputyPool->MemSize() - arrPool[14]);
	arrPool[14] = m_pDeputyPool->MemSize();
	LogDebugFmtPrint("PvpPart size=%d,difmem=%d", m_pPvpPool->MemSize(), m_pPvpPool->MemSize() - arrPool[15]);
	arrPool[15] = m_pPvpPool->MemSize();
	LogDebugFmtPrint("TreasurePart size=%d,difmem=%d", m_pTreasurePool->MemSize(), m_pTreasurePool->MemSize() - arrPool[16]);
	arrPool[16] = m_pTreasurePool->MemSize();
	LogDebugFmtPrint("CollectPart size=%d,difmem=%d", m_pCollectPool->MemSize(), m_pCollectPool->MemSize() - arrPool[17]);
	arrPool[17] = m_pCollectPool->MemSize();
	LogDebugFmtPrint("RunBusinessPart size=%d,difmem=%d", m_pRunBusinessPool->MemSize(), m_pRunBusinessPool->MemSize() - arrPool[18]);
	arrPool[18] = m_pRunBusinessPool->MemSize();
	LogDebugFmtPrint("TitlePart size=%d,difmem=%d", m_pTitlePartPool->MemSize(), m_pTitlePartPool->MemSize() - arrPool[19]);
	arrPool[19] = m_pTitlePartPool->MemSize();
	LogDebugFmtPrint("OperateWelfarePart size=%d,difmem=%d", m_pWelfarePartPool->MemSize(), m_pWelfarePartPool->MemSize() - arrPool[20]);
	arrPool[20] = m_pWelfarePartPool->MemSize();
	LogDebugFmtPrint("OperateLimitPart size=%d,difmem=%d", m_pOperateLimitPartPool->MemSize(), m_pOperateLimitPartPool->MemSize() - arrPool[21]);
	arrPool[21] = m_pOperateLimitPartPool->MemSize();
	LogDebugFmtPrint("HuoYueDuPart size=%d,difmem=%d", m_huoYueDuPartPool->MemSize(), m_huoYueDuPartPool->MemSize() - arrPool[22]);
	arrPool[22] = m_huoYueDuPartPool->MemSize();
	LogDebugFmtPrint("HorsePart size=%d,difmem=%d", m_pHorsePartPool->MemSize(), m_pHorsePartPool->MemSize() - arrPool[23]);
	arrPool[23] = m_pHorsePartPool->MemSize();
	LogDebugFmtPrint("GodPart size=%d,difmem=%d", m_pGodPartPool->MemSize(), m_pGodPartPool->MemSize() - arrPool[24]);
	arrPool[24] = m_pGodPartPool->MemSize();
	LogDebugFmtPrint("PandosPart size=%d,difmem=%d", m_pPandosPool->MemSize(), m_pPandosPool->MemSize() - arrPool[25]);
	arrPool[25] = m_pPandosPool->MemSize();
	LogDebugFmtPrint("PayPart size=%d,difmem=%d", m_pPayPool->MemSize(), m_pPayPool->MemSize() - arrPool[26]);
	arrPool[26] = m_pPayPool->MemSize();*/
}


DoubleListViewData * CreatureMgr::GetDoublelistView()
{
	return m_pDoubleListPool->MallocObj();
}
DoubleNode   * CreatureMgr::GetDoubleNode()
{
	return m_pDoubleNodePool->MallocObj();
}
void CreatureMgr::RecycleDoubleListView(DoubleListViewData * pDoubleList)
{
	m_pDoubleListPool->FreeObj(pDoubleList);
}
void CreatureMgr::RecycleDoubleNode(DoubleNode   * pDoubleNode)
{
	m_pDoubleNodePool->FreeObj(pDoubleNode);
}